Redirecting a domain with HTTPS using Amazon S3 and CloudFront

Table of Contents


This article assumes you want to redirect an entire host name to a different one, and the source host name (the one that is redirecting) should be configured to accept HTTPS connections and redirect via HTTPS. For example, this is the case if you want to redirect the www-version of a domain, such as www.example.com, to the corresponding non-www version, example.com.

Requested Redirected to
http://www.example.com/ https://example.com/
http://www.example.com/foo https://example.com/foo
https://www.example.com/ https://example.com/
https://www.example.com/foo https://example.com/foo

For the purpose of this article we'll use Amazon S3 static hosting to configure the redirect, and Amazon CloudFront to handle the HTTPS traffic. In fact, it's not possible to install a certificate for a custom name using Amazon S3 static hosting.

Initial considerations

Before we start, there are a few important notes to keep in mind:

  • As already explained, if you are using a custom domain with Amazon S3 static hosting, then you need to use CloudFront if you want to enable HTTPS. It's not possible to install a custom certificate on Amazon S3.
  • If you want the origin domain to redirect via HTTPS, then you MUST have a valid SSL/TLS certificate that covers that domain. If you have an existing certificate, then you may use that one, otherwise you will have to get a new SSL/TLS certificate from a trusted certification authority or a reseller. In this example we'll show how to use the new AWS Certificate Manager to request the certificate for free.
  • If you want to redirect the root domain (e.g. example.com) then you must use a DNS hosting provider such as DNSimple that supports CNAME-like features for the root domain (it will be explained why later). At DNSimple we call it the ALIAS record.
  • The redirect target doesn't have to be hosted on Amazon S3 or Amazon CloudFront. For example, you can deploy your site example.com on Heroku, and use Amazon S3+CloudFront to redirect another-example.com and www.another-example.com to example.com, or to redirect the www to the non-www version. This is particularly useful when your site changes domains, and you want a simple alternative to deploy a previous domain with a different certificate to your new domain, and you have a limit on the number of certificates installed per application (such as Heroku).

Configuring the Amazon S3 static site with redirect

The first step is to configure a site in Amazon S3 that will trigger the redirect. The site will be used as the origin for the CloudFront distribution.

  1. Create a new Amazon S3 bucket with exactly the same name as the origin domain. For example, if the origin is www.example-1469917820.com, then you must give the bucket the same name.

    There are several ways to create a new bucket in Amazon S3, and this is beyond the scope of this article. In this particular case, I will use the Amazon AWS web console:

    You can use the region you prefer. If you don't have a specific preference, leave US Standard.

  2. Configure the bucket to redirect all requests to another host name. Select the bucket from the list, click Properties, and in the Static Website Hosting section configure the redirect.

    The value of the Redirect all requests to field should be the domain or host name where you want to redirect the requests. In this example, it's the non-www version of the redirecting domain, but you can use any host name you want, even on a completely separate domain.

    Press Save to confirm.

  3. Before we move to the next step, take note of the Endpoint. We'll need this host name in our final step to configure Amazon CloudFront.

For the rest of the article the screenshot will use www.weppos.net as the redirect source (instead of www.example-1469917820.com) and simonecarletti.com as the target (instead of example-1469917820.com), as the other host names were just examples.

Installing the SSL certificate

As already mentioned, in order to redirect via HTTPS you need a valid SSL certificate for the redirecting host name. In this case, since I want to redirect www.weppos.net, I need an SSL certificate for it.

  • If you already have an existing SSL certificate, you need to upload the server SSL certificate to IAM.

  • If you don't have one, the simplest way to request a certificate for CloudFront is to use the Amazon Certificate Manager (ACM).

Here's the steps to request a new SSL certificate with Amazon Certificate Manager:

  1. Go to the ACM page and make sure to switch to the US East (N. Virginia) zone (us-east-1). In this case, the zone is relevant: you won't be able to use the certificate in CloudFront if it was requested in a different zone.

  2. Click Request a certificate and in the Domain name section list all the host names you want the certificate to cover. Note that you will have to validate ownership via email for each host name you enter. Keep the list short, and only add the host names you really need at this moment. You can always issue another certificate later.

    For static site redirects, I generally add only the source host name, both in www and not www form. Just note that if want to redirect www.example.com to example.com, it's sufficient to have only the first host in the certificate.

  3. Click Review and request to continue. Confirm and proceed to the validation.

  4. Read the information, and finalize the request.

  5. At the end of the request process you'll get back to the certificate list. You will find the new certificate, with a pending validation warning. This is expected, as you still need to validate the host names in order to issue the certificate.

  6. Monitor your inbox. You will receive a validation email like the following one for each host name you added into the certificate:

    Click on the links and follow the instructions.

  7. Once all the host name are validated, Amazon will issue the certificate. The state will change from pending validation to issued in the ACM console.

We are now ready to configure the HTTPS redirect in CloudFront.

Configuring the Amazon CloudFront HTTPS redirect

We have created a redirect via bucket, and we have an SSL certificate that covers the redirecting host name. The final step is to configure CloufFront with our HTTPS certificate.

  1. Go to the CloudFront page and create a new distribution:

  2. Select the Web distribution, as we want to use our Amazon AWS bucket as the distribution origin.

  3. Configure the distribution Origin Settings. Get the Amazon S3 endpoint you saved before:

    and use it as Origin Domain Name.

    Make sure to use the web site endpoint and NOT the REST endpoint, since the redirect feature is only available in the web site endpoint as explained in the Amazon documentation. Don't use the endpoint auto-suggested by CloudFront.

    Disable the SSLv3 protocol (as it's buggy and insecure) and leave the other options to defaults, unless you have specific needs.

  4. Scroll down to the Distribution Settings to configure the SSL certificate.

    In the CNAME section add the origin host name, the one that will be redirecting. In our case, it's www.weppos.net.

    Select Custom SSL Certificate and, from the drop down, select the certificate you previously requested or imported in IAM. If the certificate is not there, go back and check that you followed all the instructions contained in this article. See common errors.

  5. Confirm and create the distribution. It will take up to 10-15 minutes for the distribution to be fully deployed.

Each distribution in CloudFront has an unique CloudFront Domain Name.

You can query that host name to check if the redirect was configured properly. Here's an example of a cURL request:

$ curl -I -H 'Host: www.weppos.net' do8mh0ymnig5c.cloudfront.net
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Connection: keep-alive
Date: Sun, 31 Jul 2016 10:38:54 GMT
Location: https://simonecarletti.com/
Server: AmazonS3
X-Cache: Miss from cloudfront
Via: 1.1 87d0846629896b470e5be51235aa7aa0.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 8ZVGdzS-7aXJmsJ849TRuCIaEbp5K_UzSXaNdbFklPsV_UgNZwtz4Q==

Notice the explicit use of the Host: header. This is required as we haven't configured the redirecting www.weppos.net host name to resolve to the new CloudFront distribution yet. Therefore, querying do8mh0ymnig5c.cloudfront.net without telling Amazon what is the request host may confuse CloudFront.

If the configuration is correct, the response of the cURL request should be similar to the one above. The Location header contains the target of the redirect, which is the domain originally configured in our Amazon S3 bucket redirect.

If the configuration of the SSL certificate is correct, the cURL request will also work with HTTPS:

➜  ~ curl -I -H 'Host: www.weppos.net' https://do8mh0ymnig5c.cloudfront.net
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Connection: keep-alive
Date: Sun, 31 Jul 2016 10:38:54 GMT
Location: https://simonecarletti.com/
Server: AmazonS3
Age: 184
X-Cache: Hit from cloudfront
Via: 1.1 b1774130b147bea78a7f999710fdf47e.cloudfront.net (CloudFront)
X-Amz-Cf-Id: r2UGlaEhEq3oO1KstW82VHs_E_kSbgfs3EVlSwXJ9oI6hSp8XS3Zyg==

Pointing the DNS record to CloudFront endpoint

The final step is to configure the DNS record for the redirecting host name. The host name must point to the CloudFront distribution domain name. That way when a user visits the domain, they are redirected to the target URL.

The specific steps depend on the DNS hosting you use. The following instructions assume you are using DNSimple.

There are two possible configurations:

  • if the host name you want to redirect is a subdomain (e.g. www.example.com, blog.example.com, …) then you need to configure a CNAME that points to the Amazon CloudFront distribution endpoint

  • if the host name you want to redirect is the root domain (e.g. example.com) then you can't use a CNAME. The only way to properly configure a redirect in this case is to use a DNS provider (such as DNSimple) that supports CNAME-like features for the root domain. At DNSimple we call it the ALIAS record.

Once configured, a simple dig lookup will tell you if the DNS record resolves correctly.

$ dig www.weppos.net

; <<>> DiG 9.8.3-P1 <<>> www.weppos.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63501
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.weppos.net.			IN	A

;; ANSWER SECTION:
www.weppos.net.		3599	IN	CNAME	do8mh0ymnig5c.cloudfront.net.
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.179
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.196
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.72
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.15
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.60
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.172
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.227
do8mh0ymnig5c.cloudfront.net. 59 IN	A	54.230.25.185

As expected, a cURL request shows that the domain is successfully redirecting via HTTPS:

➜  ~ curl -I https://www.weppos.net
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Connection: keep-alive
Date: Sun, 31 Jul 2016 10:38:54 GMT
Location: https://simonecarletti.com/
Server: AmazonS3
Age: 3767
X-Cache: Hit from cloudfront
Via: 1.1 e5d27f3fb83b3b7e4d92ffc70e7b5a1f.cloudfront.net (CloudFront)
X-Amz-Cf-Id: bbhgTrFYqkjlwY22NcVIF0j8WpFQAHF-dA8jQXhYlEBtMnBwwK0peg==

Final considerations

  • This article explains how to configure the redirect for an entire domain to a different domain. It will not cover single-page redirects, that should be done by setting the redirect on a specific object uploaded to Amazon S3.

Common Errors

Certificate errors

The certificate doesn't show up in the list:

  • You didn't validate one or more host names, and the certificate was not issued
  • You didn't request the certificate in the the us-east-1 zone
  • You didn't properly import the certificate

The domain shows a certificate error:

  • Check the certificate is not self-signed
  • Check the certificate is not expired
  • Check that the domain you want to redirect is covered by the certificate

Resolution errors

The redirecting domain doesn't resolve:

  • curl: (6) Could not resolve host: something.cloudfront.net
    

    The CloudFront distribution has not been deployed yet. Check the status and make sure it's Completed and not In Progress.

  • You used a CNAME to redirect a root domain (e.g. example.com). You can't configure a CNAME for the root domain.

Redirect errors

The redirecting domain doesn't redirect:

  • Make sure you used the web site endpoint, and NOT the REST endpoint. The redirect feature is only available in the web site endpoint.
  • Check that the DNS are pointing to the CloudFront endpoint, and not to a previous server.